package com.kmxd.ams.app.arrange.command;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.kmxd.ams.client.archive.vo.ArchiveRuleFieldListVO;
import com.kmxd.ams.core.common.constant.ArchConst;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.exception.DataCheckException;
import com.kmxd.ams.infra.arrange.entity.Document;
import com.kmxd.ams.infra.arrange.entity.Volume;
import com.kmxd.ams.infra.utils.GroupUtil;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 校验相关接口
 *
 * @author ZuoLG
 */
@Slf4j
@AllArgsConstructor
@Component
public class CheckCommonCmd {

  /**
   * 对文件进行基础校验
   *
   * @param docList
   */
  public void checkBaseDoc(List<Document> docList, Boolean refresh) {
    //    try {
    if (docList.isEmpty()) {
      throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "未找到所选档案数据！");
    }

    docList.forEach(
        item -> {
          if (ObjectUtil.isEmpty(item.getYear())) {
            throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【年度】不满足操作条件！");
          }
          if (ObjectUtil.isEmpty(item.getDocSequence()) && !refresh) {
            throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【件号】不满足操作条件！");
          }
          if (ObjectUtil.isEmpty(item.getArchCode()) && !refresh) {
            throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【档号】不满足操作条件！");
          }
        });
    //    } catch (Exception e) {
    //      log.error(e.getMessage(), e);
    //      throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【档案】不满足操作条件！");
    //    }
  }

  /**
   * 对文件进行基础校验
   *
   * @param docList
   */
  public void checkBaseVol(List<Volume> docList, Boolean refresh) {
    try {
      if (docList.isEmpty()) {
        throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "未找到所选档案数据！");
      }

      docList.forEach(
          item -> {
            if (ObjectUtil.isEmpty(item.getYear())) {
              throw DataCheckException.instance(
                  ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【年度】不满足操作条件！");
            }
            if (ObjectUtil.isEmpty(item.getVolSequence()) && !refresh) {
              throw DataCheckException.instance(
                  ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【案卷号】不满足操作条件！");
            }
            if (ObjectUtil.isEmpty(item.getArchCode()) && !refresh) {
              throw DataCheckException.instance(
                  ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【档号】不满足操作条件！");
            }
          });
    } catch (DataCheckException e) {
      String message = e.getDebugMessage();
      log.error(e.getMessage(), e);
      throw DataCheckException.instance(
          ErrorCode.DATA_NOT_IN_SAME_GROUP,
          StrUtil.isBlank(message) ? "当前所选【档案】不满足操作条件！" : message);
    }
  }

  public void checkBaseDoc(List<Document> docList) {
    checkBaseDoc(docList, false);
  }

  public void checkRuleDoc(List<ArchiveRuleFieldListVO> ruleFieldList, List<Document> docList) {
    checkRuleDoc(ruleFieldList, docList, false);
  }

  /**
   * 校验文件的分组规则
   *
   * @param ruleFieldList
   * @param docList
   */
  public void checkRuleDoc(
      List<ArchiveRuleFieldListVO> ruleFieldList, List<Document> docList, boolean refresh) {
    if (ObjectUtil.isEmpty(ruleFieldList)) {
      throw DataCheckException.instance(ErrorCode.NOT_FOUND, "未找到规则信息");
    }

    // 根据规则判空
    docList.forEach(
        item -> {
          ruleFieldList.stream()
              .filter(ArchiveRuleFieldListVO::getEnableGroup)
              .forEach(
                  rule -> {
                    String field =
                        !StringUtils.isCamel(rule.getFieldCode())
                            ? StringUtils.underlineToCamel(rule.getFieldCode())
                            : rule.getFieldCode();

                    if (refresh
                        && (field.equalsIgnoreCase(ArchConst.DOC_SEQUENCE)
                            || field.equalsIgnoreCase(ArchConst.ARCH_CODE))) {
                      return;
                    }

                    Object value = getValue(item, field);
                    if (ObjectUtil.isEmpty(value)) {
                      log.info("数据 {} 校验为空", field);
                      throw DataCheckException.instance(
                          ErrorCode.VALIDATE_NOT_NULL, "当前所选【档案】" + field + " 不满足操作条件");
                    }
                  });
        });

    // 判断是否符合规则
    Map<List<Object>, List<Document>> collect =
        docList.stream()
            .collect(
                Collectors.groupingBy(
                    document -> GroupUtil.buildKey(document, ruleFieldList), Collectors.toList()));
    if (collect.size() != 1) {
      throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【档案】不满足操作条件！");
    }
  }

  /**
   * 校验文件的分组规则
   *
   * @param ruleFieldList
   * @param volumeList
   * @param refresh
   */
  public void checkRuleVol(
      List<ArchiveRuleFieldListVO> ruleFieldList, List<Volume> volumeList, boolean refresh) {
    if (ObjectUtil.isEmpty(ruleFieldList)) {
      throw DataCheckException.instance(ErrorCode.NOT_FOUND, "未找到规则信息");
    }

    // 根据规则判空
    volumeList.forEach(
        item -> {
          ruleFieldList.stream()
              .filter(ArchiveRuleFieldListVO::getEnableGroup)
              .forEach(
                  rule -> {
                    String field =
                        !StringUtils.isCamel(rule.getFieldCode())
                            ? StringUtils.underlineToCamel(rule.getFieldCode())
                            : rule.getFieldCode();

                    if (refresh
                        && (field.equalsIgnoreCase(ArchConst.VOL_SEQUENCE)
                            || field.equalsIgnoreCase(ArchConst.ARCH_CODE))) {
                      return;
                    }

                    Object value = getValue(item, field);
                    if (ObjectUtil.isEmpty(value)) {
                      log.info("数据校验 {} 为空", field);
                      throw DataCheckException.instance(ErrorCode.NOT_FOUND, "当前所选【档案】不满足操作条件");
                    }
                  });
        });

    // 判断是否符合规则
    Map<List<Object>, List<Volume>> collect =
        volumeList.stream()
            .collect(
                Collectors.groupingBy(
                    volume -> GroupUtil.buildKey(volume, ruleFieldList), Collectors.toList()));
    if (collect.size() != 1) {
      throw DataCheckException.instance(ErrorCode.DATA_NOT_IN_SAME_GROUP, "当前所选【档案】不满足操作条件！");
    }
  }

  /**
   * 获取doc对象的值
   *
   * @param document
   * @param fieldKey
   * @return
   */
  public String getValue(Object document, String fieldKey) {
    JSONConfig jsonConfig = JSONConfig.create().setDateFormat(DatePattern.PURE_DATE_PATTERN);
    String jsonStr = JSONUtil.toJsonStr(document, jsonConfig);
    JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
    String value = jsonObject.getStr(fieldKey);
    return value;
  }
}
